package com.atomos.system
{
	import com.atomos.particle.Particle;
	import com.atomos.particle.ParticleManager;
	import com.atomos.strategy.action.ActionStrategy;
	import com.atomos.strategy.action.MockAction;
	import com.atomos.strategy.emission.MockAbstractEmission;
	import com.atomos.strategy.emission.MockAtStartEmission;
	import com.atomos.strategy.initialize.InitializeStrategy;
	import com.atomos.strategy.initialize.MockInitializer;
	import com.bourre.collection.Iterator;
	import com.bourre.collection.WeakCollection;
	import com.kairos.engine.MockRTBeacon;
	
	import flexunit.framework.TestCase;	

	public class SimpleParticleSystemTest extends TestCase
	{
		protected var _system : SimpleParticleSystem;
		protected var _manager : ParticleManager;
		
		public override function setUp():void
		{
			_system = new SimpleParticleSystem ();
			_manager = ParticleManager.getInstance();
			
			_system.setTickBeacon( MockRTBeacon.getInstance() );
			
			MockRTBeacon.getInstance().setStep( 100 );
		}
		public override function tearDown():void
		{
			_system.release();
			ParticleManager.release();
			_system = null;
		}
		
		public function testConstruct () : void
		{
			assertNotNull( "Constructor failed to create an instance", _system );
			
			assertEquals( "Constructor failed to register the particles system to the manager",
						  1, _manager.getParticleSystemsCount() );
						  
			_system.release();
			
			assertEquals( _system + ".release() failed to unregister it from the manager",
						  0, _manager.getParticleSystemsCount() );
		}
		
		public function testEmit () : void
		{
			
			var emission : MockAbstractEmission = new MockAbstractEmission( Particle );
			var n : Number = 0;
			
			assertFalse( _system + ".isEmitting() don't return false with no emission", _system.isEmitting() );
			
			_system.emit( emission );
			
			assertEquals( _system + " failed to register emission", 1, _system.getEmissionsCount() );
			assertTrue( _system + ".isEmitting() don't return true with an emission", _system.isEmitting() );
			
			MockRTBeacon.getInstance().onTick();
			
			assertEquals ( _system + " generated particles haven't been registered", 10, _system.getParticlesCount() );
			assertEquals ( _system + " generated particles haven't been registered in manager", 10, _manager.getParticlesCount() );
			
			var col : WeakCollection = _system.getParticles();
			
			assertNotNull( _system + ".getParticles() don't return a valid collection", col );
			assertEquals( _system + ".getParticles().size() don't return the correct number of particles", 10, col.size() );
			
			assertEquals( _system + " failed to remove emission after process", 0, _system.getEmissionsCount() );
			assertFalse( _system + ".isEmitting() don't return false with no emission", _system.isEmitting() );
			
			var i : Iterator = col.iterator();
			
			while( i.hasNext() )
			{
				var p : Particle = i.next() as Particle;
				
				assertNotNull( "Generated particle at " + n + " isn't valid", p );
				
				n++;
			}
		}
		
		public function testEmitAtStart () : void
		{
			
			var emission : MockAtStartEmission = new MockAtStartEmission( Particle );
			var n : Number = 0;
			
			_system.emit( emission );

			assertEquals ( _system + " generated particles haven't been registered", 10, _system.getParticlesCount() );
			assertEquals ( _system + " generated particles haven't been registered in manager", 10, _manager.getParticlesCount() );
			
			var col : WeakCollection = _system.getParticles();
			
			assertNotNull( _system + ".getParticles() don't return a valid collection", col );
			assertEquals( _system + ".getParticles().size() don't return the correct number of particles", 10, col.size() );
			
			assertEquals( _system + " failed to remove emission after process", 0, _system.getEmissionsCount() );
			assertFalse( _system + ".isEmitting() don't return false with no emission", _system.isEmitting() );
			
			var i : Iterator = col.iterator();
			
			while( i.hasNext() )
			{
				var p : Particle = i.next() as Particle;
				
				assertNotNull( "Generated particle at " + n + " isn't valid", p );
				
				n++;
			}
		}
		
		public function testGetSetAction () : void
		{
			var action : ActionStrategy = new MockAction();
			
			_system.setAction( action );
			
			assertNotNull ( _system + ".setAction() set a null action", _system.getAction() );
			assertEquals ( _system + ".getAction() don't return the previously defined action", action, _system.getAction() );
			
			_system.setAction( null );
			
			assertNotNull ( _system + ".setAction() failed with a null argument", _system.getAction() );
		}
		
		public function testGetSetInitializer () : void
		{
			var initializer : InitializeStrategy = new MockInitializer();
			
			_system.setInitializer( initializer );
			
			assertNotNull ( _system + ".setInitializer() set a null action", _system.getInitializer() );
			assertEquals ( _system + ".getInitializer() don't return the previously defined action", initializer, _system.getInitializer() );
			
			_system.setInitializer( null );
			
			assertNotNull ( _system + ".setInitializer() failed with a null argument", _system.getInitializer() );
		}
	}
}